package repository

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Differ"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
)

type repoLocalJarFileCompScanner struct {
}

func (e *repoLocalJarFileCompScanner) ScanRepoCompEntity(dstEntityMap map[string]*edgeEntity.RepoCompEntity) {
	srcEntityMap := make(map[string]*edgeEntity.RepoCompEntity)
	commEntityManager.FindEntityList(edgeEntity.Type.RepoCompEntity.Type(), func(value commEntity.IEntity) bool {
		compEntity := value.(*edgeEntity.RepoCompEntity)

		if "local" != compEntity.CompRepo {
			return false
		}
		if "jar-decoder" != compEntity.CompType {
			return false
		}
		fileName, ok := compEntity.CompParam["fileName"]
		if !ok {
			return false
		}

		srcEntityMap[fileName.(string)] = compEntity

		return true
	})

	addList := make(map[string]interface{})
	delList := make(map[string]interface{})
	eqlList := make(map[string]interface{})
	Differ.Set.DifferByKey(srcEntityMap, dstEntityMap, &addList, &delList, &eqlList)

	// 只新增，不主动删除。因为operate是用户手动维护的
	for key, _ := range addList {
		srcEntity := dstEntityMap[key]

		commEntityManager.InsertEntity(srcEntity)
	}

	// 更新compParam中的file属性，这个属性是这边维护的
	for key, _ := range eqlList {
		srcEntity := srcEntityMap[key]
		dstEntity := dstEntityMap[key]

		srcManufacturer := Map.GetString(srcEntity.CompParam, "manufacturer", "")
		dstManufacturer := Map.GetString(dstEntity.CompParam, "manufacturer", "")

		srcDeviceType := Map.GetString(srcEntity.CompParam, "deviceType", "")
		dstDeviceType := Map.GetString(dstEntity.CompParam, "deviceType", "")

		// 检查：是否发生了变化
		if dstDeviceType == srcDeviceType && dstManufacturer == srcManufacturer {
			continue
		}

		// 检查：是否为默认的缺省值，避免覆盖用户输入
		if "Fox-Edge" == dstManufacturer && "public" == dstDeviceType {
			continue
		}

		// 修改内容
		srcEntity.CompParam["manufacturer"] = dstManufacturer
		srcEntity.CompParam["deviceType"] = dstDeviceType

		commEntityManager.UpdateEntity(srcEntity)
	}
}

func (e *repoLocalJarFileCompScanner) ScanRepoCompEntityByJarMethod() (map[string]*edgeEntity.RepoCompEntity, error) {
	operateEntityList, err := commEntityManager.GetEntityMap(edgeEntity.Type.OperateMethodEntity.Type())
	if err != nil {
		return nil, err
	}

	fileNameMap := make(map[string]*edgeEntity.RepoCompEntity)
	for _, entity := range operateEntityList {
		operateEntity := entity.(*edgeEntity.OperateMethodEntity)

		if operateEntity.EngineType == "JavaScript" {
			continue
		}

		// 从JAR类型的Operate中获得JAR的文件名
		fileName := Map.GetString(operateEntity.EngineParam, "file", "")
		if fileName == "" {
			continue
		}

		// 构造缺省的RepoCompEntity
		localMap, err := LocalCompConvert.ConvertOperateEntity2Local(operateEntity)
		if err != nil {
			return nil, err
		}

		compEntity, err := LocalCompBuilder.BuildCompEntity(localMap)
		if err != nil {
			return nil, err
		}

		fileNameMap[fileName] = compEntity
	}

	return fileNameMap, nil
}
